Backlogに課題が追加されたらPagerDutyのインシデントが作成されるようにしてみた

Backlogに課題が追加されたらPagerDutyのインシデントが作成されるようにしてみた

Clock Icon2024.08.21

はじめに

リテールアプリ共創部のるおんです。
皆さん、プロジェクト管理ツールには何を使っていますか?
私のチームでは主にBacklogを使用して、顧客やチームメンバーとコミュニケーションを取っています。しかし、業務で集中している時にお客様からの新しいメッセージや新しい課題の起票に気づかないことがあります。
メールで通知を受け取ったり、Slackに通知を送ったりして通知を一元化することでこの問題を解決しようとしてきましたが、結局これらの方法も見逃してしまうことが多いです。また、何が重要で、誰が迅速に対応すべきかなどもパッと見で判断することができないと思います。
そこで、PagerDutyを連携させることで、Backlogに課題が追加された際に、インシデントを作成しBacklogの内容を共有することで、スマートフォンなどのモバイル端末へ直接通知やコールを受けることができ、重要な通知を見逃す可能性が大幅に減るのではないでしょうか?

ということで、今回はこのBacklogとPagerDutyの連携を実際に試してみたので、その方法を共有したいと思います。

全体像

まずBacklogで新しく「課題が追加」された際にBacklogのwebhookが起動するように設定します。webhookからAPI Gatewayのエンドポイントを呼び出すことで、Lambda関数を実行し、そのLambda関数内でPagerDuty Events API V2を使用してインシデントを作成します。
これによって、Backlogの課題管理とPagerDutyのインシデント管理を連携させます。
構成図は以下の通りです。

スクリーンショット 2024-08-22 9.51.11

やってみた

手順の概要は以下の通りです。

  1. PagerDutyの設定
  2. API GatewayとLambda関数の用意
  3. Backlogのwebhookの設定

1. PagerDutyの設定

PagerDutyで新しいサービスを作成し、API連携を有効にします。今回使用するAPIは、PagerDuty Events API V2です。

PagerDuty Events API V2の使用方法は、以下のブログで詳しく解説しているので、今回は省略します。
https://dev.classmethod.jp/articles/pagerduty-events-api-v2/

サービスを作成したら、Integration Keyを控えておいてください。後ほど作成するLambda関数内で使用します。
iztmswgvuz5w2j9nkxgj

2. API GatewayとLambda関数の作成

次に、Backlogからのwebhookを受け取り、PagerDutyにインシデントを作成するLambda関数を作成します。使用した言語はTypeScriptで、以下のようにコードを記述してみました。

export const handler = async (event) => {
    try {
        console.log(event)
        // Parse the incoming webhook payload from Backlog
        const body = JSON.parse(event.body);

        if (body.type !== 1) {
            return {
                statusCode: 200,
                body: JSON.stringify({ message: '課題追加以外のアクションです' })
            };
        }

        const getSeverity = (priorityId) => {
            switch(priorityId){
                case 4:
                    return 'info'
                case 3:
                    return 'warning'
                case 2:
                    return 'critical'
                default:
                throw new Error('不適切な優先度が入力されました。')
            }
        }

        // BackLogから必要な項目を抽出
        const { content, project } = body;
        // タイトル
        const summary = `New Backlog Issue: ${content.summary}`;
        // 重要度
        const severity = getSeverity(content.priority.id)
        // ソース
        const source = project.projectKey;
        const customDetails = {
            '課題タイプ': content.issueType.name,
            '課題の詳細': content.description,
            '優先度': content.priority.name,
        };

        // Prepare the payload for PagerDuty
        const pagerDutyParams = {
            routing_key: PAGERDUTY_INTEGRATION_KEY, // 先ほどのIntegration Keyを指定
            event_action: 'trigger',
            payload: {
                summary: summary,
                source: source,
                severity: severity, 
                custom_details: customDetails
            }
        };

        // Send the event to PagerDuty using fetch
        const response = await fetch('https://events.pagerduty.com/v2/enqueue', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(pagerDutyParams)
        });

        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }

        const data = await response.json();
        console.log('PagerDuty Response:', data);

        return {
            statusCode: 200,
            body: JSON.stringify({ message: 'PagerDuty incident created successfully.' })
        };
    } catch (error) {
        console.error('Error:', error);
        return {
            statusCode: 500,
            body: JSON.stringify({ message: 'Error creating PagerDuty incident.' })
        };
    }
};

Lambda関数のeventに渡されるbodyの中のcontentの中にBacklogの課題の内容が含まれています。
summaryの中身が課題のタイトルです。
また、customDetailsとして課題のタイプや詳細、優先度を表示させるようにしました。
優先度に応じでインシデントの重要度(severity)を対応できるようにしてみました。

HTTPリクエストメソッドはPOSTで、エンドポイントはhttps://events.pagerduty.com/v2/enqueueです。

このLambda関数をデプロイし、API Gatewayと連携させます。

3. Backlogのwebhook設定

最後に、Backlogの管理画面からwebhookを設定します。
「課題の追加」にチェックを入れて、エンドポイントURLに先ほど作成したAPI GatewayのURLを入力します。

スクリーンショット 2024-08-21 21.45.39

以上で設定は完了です。

動作確認

それでは、実際に動作確認をしてみましょう。
以下のように、Backlogで新しい課題を作成してみました。
スクリーンショット 2024-08-21 22.07.05

すると、PagerDutyにインシデントが作成され、手元のスマホに通知が届きました。
IMG_0639
アプリ上でも、ブラウザ上でもインシデントが作成されていることが確認できます。
IMG_0640
スクリーンショット 2024-08-21 22.12.44

終わりに

今回は、BacklogとPagerDutyの連携を AWS Lambda と API Gateway を使って実装してみました。この仕組みを使うことで、重要な課題が追加されたときに即座にチーム全体に通知することができ、迅速な対応が可能になるのではないでしょうか。

今回はとりあえず課題の追加に焦点を当てて、 簡単にBacklogとPagerDutyを連携させてみましたが、コメントの追加に合わせてインシデント内にNoteが作成したり、課題の削除に伴ってインシデントを削除する仕組みなども作るとより実践的になると思います。

また、Backlog課題に割振られた担当者にPagerDutyの通知を送ることができないかと少し考えましたが、Backlogのwebhookから送られるパラメーターに担当者のメールアドレス情報が含まれていなかったため、PagerDutyにその情報を送ることができず、通知の割り振りをうまくすることができませんでした。

解決案として、DB内にメンバーのユーザー名を格納したテーブルを用意しておき、webhookから送られる担当者名の情報と照らし合わせることで通知の割り振りなどもできるかと考えました。しかし実装コストがかかることや、ユーザー名を変更したときに機能しないことなど考慮すべき点がありそうです。
他に良さそうな方法があれば教えてください。

今後はこの機能をより実践的にするために、コメント追加や、課題の更新・削除に合わせてインシデントを連携させたいと思います。

参考になれば幸いです。

参考

Backlog
PagerDuty Events API V2

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.